/****************************************************************************************
**  File: Box.hpp
**  Author: Asteroth
**  Date: 22/02/2009
****************************************************************************************/

#ifndef __BOX_HPP__
#define __BOX_HPP__

template <class T>
class Boxx
{
    public:
        T X, Y, Z, W, H, D;

        // --- Constructors ----------------------------------------------------
        Boxx();
        Boxx( const Boxx<T> &box );
        Boxx( T x, T y, T z, T w, T h, T d );

        // --- Operators -------------------------------------------------------
        // a = b
        inline Boxx<T> &operator = ( const Boxx<T> &set );
        // a += b   a + b  ->  results a cube containing both
        inline Boxx<T> &operator += ( const Boxx<T> &add );
        inline Boxx<T> operator + ( const Boxx<T> &add ) const;
        // inside: a[ b ]  ->  b inside a
        inline bool operator [] ( const Vector3x<T> &vect ) const;
        inline bool operator [] ( const Boxx<T> &box ) const;
};

typedef Boxx<float> Box;

template <class T> Boxx<T>::Boxx()
    { X = (T)0.0; Y = (T)0.0; Z = (T)0.0; W = (T)0.0; H = (T)0.0; D = (T)0.0; }
template <class T> Boxx<T>::Boxx( const Boxx<T> &box )
    { X = box.X; Y = box.Y; Z = box.Z; W = box.W; H = box.H; D = box.D; }
template <class T> Boxx<T>::Boxx( T x, T y, T z, T w, T h, T d )
    { X = x; Y = y; Z = z; W = w; H = h; D = d; }

template <class T> inline Boxx<T> &Boxx<T>::operator = ( const Boxx<T> &set )
    { X = set.X; Y = set.Y; Z = set.Z; W = set.W; H = set.H; D = set.D; return *this; }
template <class T> inline Boxx<T> &Boxx<T>::operator += ( const Boxx<T> &add )
    { X = eMin( X, add.X ); Y = eMin( Y, add.Y ); Z = eMin( Z, add.Z ); W = eMax( W, add.W ); H = eMax( H, add.H ); D = eMax( D, add.D ); return *this; }
template <class T> inline Boxx<T> Boxx<T>::operator + ( const Boxx<T> &add ) const
    { return Boxx<T>( eMin( X, add.X ), eMin( Y, add.Y ), eMin( Z, add.Z ), eMax( W, add.W ), eMax( H, add.H ), eMax( D, add.D ) ); }
template <class T> inline bool Boxx<T>::operator [] ( const Vector3x<T> &vect ) const
    { if ( vect.X >= X && vect.Y >= Y && vect.Z >= Z && vect.X < X + W && vect.Y < Y + H && vect.Z < Z + D ) return true; return false; }
template <class T> inline bool Boxx<T>::operator [] ( const Boxx<T> &box ) const
    { if ( box.X >= X && box.Y >= Y && box.Z >= Z && box.X + box.W <= X + W && box.Y + box.H <= Y + H && box.Z + box.D <= Z + D ) return true; return false; }

#endif
